﻿using KBWebApi.Common;
using KBWebApi.Model;
using KBWebApi.Bll;
using System;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace KBWebApi.Bll
{
    /// <summary>
    /// token提供类
    /// </summary>
    public class TokenProvider
    {
        readonly TokenProvidorOptions tokenProvidorOptions;

        public TokenProvider(TokenProvidorOptions _tokenProvidorOptions)
        {
            tokenProvidorOptions = _tokenProvidorOptions;
        }

        /// <summary>
        /// 创建token
        /// </summary>
        /// <param name="DcdUserID">用户id</param>
        /// <param name="password">密码</param>
        /// <param name="isEncrypt">是否加密</param>
        /// <returns></returns>
        public async Task<TokenEntity> GenerateToken(string DcdUserID, string password, bool isEncrypt)
        {
            var identity = await GetIdentity(DcdUserID);
            if (identity == null)
            {
                return new TokenEntity { status = 0, message = "登录失败，令牌失效" };
            }
            UserDto userReturn = new UserDto();
            string PasswordKey = password;
                if ((!isEncrypt))
                {
                    PasswordKey = DESHelper.DesEncrypt(password);
                }
                userReturn = await UserBll.GetUser(DcdUserID, PasswordKey);
                if (userReturn.UserId == null)
                {
                    return new TokenEntity { status = 0, message = "登录失败，请联系管理员" };
                }

            var now = DateTime.UtcNow;
            //声明参数
            var claims = new Claim[]
            {
                new Claim(JwtRegisteredClaimNames.Sub,DcdUserID),
                new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Iat,ToUnixEpochDate(now).ToString()),
                new Claim(ClaimTypes.Surname,userReturn.UserName,ClaimValueTypes.String),
            };
            try
            {
                //jwt安全令牌
                var jwt = new JwtSecurityToken(
                    issuer: tokenProvidorOptions.Issuer,
                    audience: tokenProvidorOptions.Audienc,
                    notBefore: now,
                    claims: claims,
                    expires: now.Add(tokenProvidorOptions.Expiration),
                    signingCredentials: tokenProvidorOptions.signingCredentials
                    );
                var encodeJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
                string token = MD5Provider.Hash(encodeJwt);
                //string sql = $"update UserFile set ShortChar05=N'{token}' where DcdUserID='{DcdUserID}' and MobilePassword=N'{PasswordKey}'";
                //await Task.Run(() => SqlDBHelper.SqlHelper.ExecteNonQueryText(sql, null));
                string[] Role = null;
                if (userReturn.Role.Contains(","))
                {
                    Role = userReturn.Role.Split(',');
                }
                else
                {
                    Role = new string[] { userReturn.Role };
                }
                var response = new TokenEntity
                {
                    status = 1,
                    name = userReturn.UserName,
                    userId = userReturn.UserId,
                    message = "登录成功！",
                    access_token = encodeJwt,
                    expires_in = (int)tokenProvidorOptions.Expiration.TotalSeconds
                };
                WriteLog.Writelog("登录成功！" + DcdUserID + "  " + userReturn.UserName);
                return response;
            }
            catch (Exception x)
            {
                WriteLog.Writelog("GenerateToken=>" + x.ToString());
                return null;
            }
            //生成令牌字符串        
        }

        public static long ToUnixEpochDate(DateTime date)
        {
            return (long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
        }
        private Task<ClaimsIdentity> GetIdentity(string DcdUserID)
        {
            return Task.FromResult(
                new ClaimsIdentity(new System.Security.Principal.GenericIdentity(DcdUserID, "token"),
                new Claim[] { new Claim(ClaimTypes.Name, DcdUserID) })
                );
        }
    }
}
